package com.example.xinli.service.serviceImpl;

import com.alibaba.excel.EasyExcelFactory;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.xinli.dao.*;
import com.example.xinli.domain.dto.InquiryResExcelDto;
import com.example.xinli.domain.entity.*;
import com.example.xinli.domain.entity.Record;
import com.example.xinli.domain.vo.ExcelEvalVO;
import com.example.xinli.domain.vo.InterAnswerReturnVo;
import com.example.xinli.service.IInquiryService;
import com.example.xinli.service.IToolService;
import com.example.xinli.domain.vo.ResponseBean;
import com.example.xinli.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.MinioException;

import javax.servlet.ServletOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class ToolServiceImpl extends ServiceImpl<InquiryResultMapper, InquiryResult> implements IToolService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IInquiryService inquiryService;
    @Autowired
    private InquiryResultMapper inquiryResultMapper;
    /**
     *
     * @param imgFile
     * @return
     */
    @Value("${minio.endpoint}")
    private String endpoint;

    @Value("${minio.access-key}")
    private String accessKey;

    @Value("${minio.secret-key}")
    private String secretKey;
    @Autowired
    private AnswerMapper answerMapper;
    @Autowired
    private RecordMapper recordMapper;

    @Autowired
    private EvalMapper evalMapper;


    public ResponseBean uploadImg(MultipartFile imgFile,String name) {
        String baseURL="http://115.159.83.61:9000/common";
        String originalFilename = imgFile.getOriginalFilename();
        String newFilename = name;
        try {
            // Create a minioClient with the MinIO server playground, its access key and secret key.
            MinioClient minioClient =
                    MinioClient.builder()
                            .endpoint(endpoint)
                            .credentials(accessKey, secretKey)
                            .build();



            // Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket
            // 'asiatrip'.
//            minioClient.uploadObject(
//                    UploadObjectArgs.builder()
//                            .bucket("mindease")
//                            .object(newFilename)
//                            .stream(file.getInputStream(), file.getSize(), -1) // 使用MultipartFile对象的输入流来上传文件
//                            .build());

            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket("mindease")
                            .object(newFilename)
                            .stream(imgFile.getInputStream(), imgFile.getSize(), -1) // 使用MultipartFile对象的输入流来上传文件
                            .contentType(imgFile.getContentType()) // 设置内容类型
                            .build()
            );
            log.info(newFilename+ " is successfully uploaded as " + "object");


        } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
            System.out.println("Error occurred: " + e);
            e.printStackTrace();

        }
        return new ResponseBean(200, "上传成功", baseURL+"/"+newFilename);
    }

    public ResponseBean uploadFile(InputStream inputStream, String fileName, long fileSize, String contentType) {
        String bucketName="excel";
        String baseURL="https://minio.mindease.online/"+bucketName;
        String FileURL = "http://mindease.online:9000/"+bucketName;  // MinIO 服务器的基地址
        String newFilename = fileName;  // 生成一个新的文件名



//        上传文件必须用备案的域名
        try {
            // 创建一个 MinIO 客户端
            MinioClient minioClient =
                    MinioClient.builder()
                            .endpoint("http://mindease.online:9000")
                            .credentials("81ANNS1kz7AefpMn7cLk", "xdJBJWc1Fjoxx1Lex0iApSTOnn3TdbaaBcAAF9oC")
                            .build();

            // 上传文件到 MinIO
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)  // 指定要上传的 bucket 名称
                            .object(newFilename)  // 设置上传到 MinIO 的文件名
                            .stream(inputStream, fileSize, -1)  // 使用 InputStream 上传
                            .contentType(contentType != null ? contentType : "application/octet-stream")  // 设置文件的内容类型，如果没有则使用默认的
                            .build()
            );
            log.info(newFilename + " is successfully uploaded as an object");

        } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) {
            log.error("Error occurred while uploading file: " + e.getMessage(), e);
            return new ResponseBean(500, "文件上传失败", null);  // 返回失败的响应
        }

//        log.info("111");

        // 上传成功后返回文件的下载地址
        return new ResponseBean(200, "上传成功", baseURL + "/" + newFilename);
    }

    @Override
//    public void downloadExcel(ServletOutputStream outputStream) {
//        EasyExcelFactory.write(outputStream, InquiryResExcelDto.class).sheet("问卷结果").doWrite(this.getInquiryResList());
//    }
    public void downloadevalExcel(ByteArrayOutputStream byteArrayOutputStream){


        try {
            // 使用 EasyExcel 写入 ByteArrayOutputStream 而不是 ServletOutputStream
            EasyExcelFactory.write(byteArrayOutputStream, ExcelEvalVO.class)
                    .sheet("评估结果")
                    .doWrite(this.getEvalResList());
        } catch (Exception e) {
            log.error("生成 Excel 文件失败", e);
            throw new RuntimeException("生成 Excel 文件失败", e);
        }
    }
    public void downloadSingleExcel(ByteArrayOutputStream byteArrayOutputStream,String id) {
        try {
            // 使用 EasyExcel 写入 ByteArrayOutputStream 而不是 ServletOutputStream
            EasyExcelFactory.write(byteArrayOutputStream, InquiryResExcelDto.class)
                    .sheet("问卷填写结果")
                    .doWrite(this.getInquiryResListByid(id));
        } catch (Exception e) {
            log.error("生成 Excel 文件失败", e);
            throw new RuntimeException("生成 Excel 文件失败", e);
        }
    }

    public void downloadInterResExcel(ByteArrayOutputStream byteArrayOutputStream,String id) {
        try {
            // 使用 EasyExcel 写入 ByteArrayOutputStream 而不是 ServletOutputStream
            EasyExcelFactory.write(byteArrayOutputStream, InterAnswerReturnVo.class)
                    .sheet("干预填写结果")
                    .doWrite(this.getInterAnswerResListByid(id));
        } catch (Exception e) {
            log.error("生成 Excel 文件失败", e);
            throw new RuntimeException("生成 Excel 文件失败", e);
        }
    }

    @Override
//    public void downloadExcel(ServletOutputStream outputStream) {
//        EasyExcelFactory.write(outputStream, InquiryResExcelDto.class).sheet("问卷结果").doWrite(this.getInquiryResList());
//    }

    public void downloadExcel(ByteArrayOutputStream byteArrayOutputStream) {
        try {
            // 使用 EasyExcel 写入 ByteArrayOutputStream 而不是 ServletOutputStream
            EasyExcelFactory.write(byteArrayOutputStream, InquiryResExcelDto.class)
                    .sheet("问卷结果")
                    .doWrite(this.getInquiryResList());
        } catch (Exception e) {
            log.error("生成 Excel 文件失败", e);
            throw new RuntimeException("生成 Excel 文件失败", e);
        }
    }

    private List<ExcelEvalVO> getEvalResList() {
        QueryWrapper<Eval> queryWrapper = new QueryWrapper<>();
        List<Eval> evals = evalMapper.selectList(queryWrapper);

        List<ExcelEvalVO> excelEvalVOS=new ArrayList<ExcelEvalVO>();

        Set<String> openIds = evals.stream().map(Eval::getUserId).collect(Collectors.toSet());

        //建立openid和phone的对应
        // 批量查询用户电话
        Map<String, String> userPhones = userService.getUserPhonesByIds(openIds);

        Map<String, String> userIdExid= userService.getUserExidByIds(openIds);

        log.info("userIdExid");
        log.info(userIdExid.toString());

        for (Eval eval : evals) {
            ExcelEvalVO excelEvalVO = new ExcelEvalVO();
            excelEvalVO.setInterId(eval.getInterId());
            excelEvalVO.setPhone(userPhones.get(eval.getUserId()));

            excelEvalVO.setExId(userIdExid.get(excelEvalVO.getPhone()));
            excelEvalVO.setExperienceScore(eval.getExperienceScore());
            excelEvalVO.setHarvestScore(eval.getHarvestScore());
            excelEvalVO.setHelpfulContent(eval.getHelpfulContent());

            excelEvalVOS.add(excelEvalVO);

        }
        return excelEvalVOS;


    }

    private List<InquiryResExcelDto> getInquiryResListByid(String id) {
        log.info("id:{}",id);
        QueryWrapper<InquiryResult> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("position", pos);
        queryWrapper.eq("user_id",id);
        List<InquiryResult> inquiryRes = baseMapper.selectList(queryWrapper);

        List<InquiryResExcelDto> inquiryResExcelDtos=new ArrayList<InquiryResExcelDto>();
        //把inquiryRes转换为InquiryResExcelDto

        // 获取单个用户的电话
        String userPhone = userService.getUserPhoneById(id);

        Set<Integer> inquiryIds = inquiryRes.stream().map(InquiryResult::getInquiryId).collect(Collectors.toSet());

        log.info("inquiryIds:{}",inquiryIds);

        // 批量查询选项
        Map<Integer, String> inquiryOptions = inquiryService.getOptionsByInquiryIds(inquiryIds);

        // 批量查询问题
        Map<Integer, String> inquiryQuestions = inquiryService.getQuestionsByInquiryIds(inquiryIds);

        for (InquiryResult inquiryResult : inquiryRes) {
            InquiryResExcelDto inquiryResExcelDto = new InquiryResExcelDto();
            inquiryResExcelDto.setInquiryId(inquiryResult.getInquiryId());

            // 设置单个用户的电话
            inquiryResExcelDto.setPhone(userPhone);

            inquiryResExcelDto.setInterId(inquiryResult.getInterId());

            // 从 Map 中获取选项和问题
            inquiryResExcelDto.setOptions(inquiryOptions.get(inquiryResult.getInquiryId()));
            inquiryResExcelDto.setQuestion(inquiryQuestions.get(inquiryResult.getInquiryId()));

            inquiryResExcelDto.setScore(inquiryResult.getScore());
            inquiryResExcelDto.setFinishedTime(inquiryResult.getFinishedTime());
            inquiryResExcelDto.setText(inquiryResult.getText());

            inquiryResExcelDtos.add(inquiryResExcelDto);

//            log.info("111");
        }
        return inquiryResExcelDtos;
    }

    private List<InterAnswerReturnVo> getInterAnswerResListByid(String id) {
        log.info("id:{}",id);
        List<InterAnswerReturnVo> interAnswerReturnList = new ArrayList<InterAnswerReturnVo>();

        QueryWrapper<Answer> answerQueryWrapper = new QueryWrapper<>();
        answerQueryWrapper.eq("user_id",id);

        String userPhone = userService.getUserPhoneById(id);

        List<Answer> answerList = answerMapper.selectList(answerQueryWrapper);
        for (Answer answer : answerList) {
            QueryWrapper<Record> recordQueryWrapper = new QueryWrapper<>();
            recordQueryWrapper.eq("record_id",answer.getRecordId());
            Record record = recordMapper.selectOne(recordQueryWrapper);

            // 获取 inputPages 和 inputContent 的分割内容
            List<String> inputPagesList = Arrays.asList(answer.getInputPages().split("#"));
            List<String> inputContentList = Arrays.asList(answer.getInputContent().split("#"));

            // 遍历 inputPagesList 和 inputContentList，生成对应的 InterAnswerReturnVo 对象
            for (int i = 0; i < inputPagesList.size(); i++) {
                InterAnswerReturnVo interAnswerReturnVo = new InterAnswerReturnVo();

                // 设置通用属性
                interAnswerReturnVo.setInterId(record.getInterId());
                interAnswerReturnVo.setPhone(userPhone);
                interAnswerReturnVo.setRecordId(record.getRecordId());
                interAnswerReturnVo.setStartTime(record.getStartTime());
                interAnswerReturnVo.setEndTime(record.getEndTime());

                // 设置当前对象的 inputPage 和 inputContent
                interAnswerReturnVo.setInputPage(inputPagesList.get(i));
                interAnswerReturnVo.setInputContent(inputContentList.get(i));

                // 添加到结果列表
                interAnswerReturnList.add(interAnswerReturnVo);
            }
        }

        return interAnswerReturnList;
    }

    private List<InquiryResExcelDto> getInquiryResList() {
        QueryWrapper<InquiryResult> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("position", pos);

        List<InquiryResult> inquiryRes = baseMapper.selectList(queryWrapper);

        List<InquiryResExcelDto> inquiryResExcelDtos=new ArrayList<InquiryResExcelDto>();
        //把inquiryRes转换为InquiryResExcelDto

        // 收集所有userId和inquiryId
        Set<String> userIds = inquiryRes.stream().map(InquiryResult::getUserId).collect(Collectors.toSet());
        Set<Integer> inquiryIds = inquiryRes.stream().map(InquiryResult::getInquiryId).collect(Collectors.toSet());

        // 批量查询用户电话
        Map<String, String> userPhones = userService.getUserPhonesByIds(userIds);

        // 批量查询选项
        Map<Integer, String> inquiryOptions = inquiryService.getOptionsByInquiryIds(inquiryIds);

        // 批量查询问题
        Map<Integer, String> inquiryQuestions = inquiryService.getQuestionsByInquiryIds(inquiryIds);

        for (InquiryResult inquiryResult : inquiryRes) {
            InquiryResExcelDto inquiryResExcelDto = new InquiryResExcelDto();
            inquiryResExcelDto.setInquiryId(inquiryResult.getInquiryId());

            // 从 Map 中获取电话
            inquiryResExcelDto.setPhone(userPhones.get(inquiryResult.getUserId()));

            inquiryResExcelDto.setInterId(inquiryResult.getInterId());

            // 从 Map 中获取选项和问题
            inquiryResExcelDto.setOptions(inquiryOptions.get(inquiryResult.getInquiryId()));
            inquiryResExcelDto.setQuestion(inquiryQuestions.get(inquiryResult.getInquiryId()));

            inquiryResExcelDto.setScore(inquiryResult.getScore());
            inquiryResExcelDto.setFinishedTime(inquiryResult.getFinishedTime());
            inquiryResExcelDto.setText(inquiryResult.getText());

            inquiryResExcelDtos.add(inquiryResExcelDto);

//            log.info("111");
        }
        return inquiryResExcelDtos;
    }

}
